from DataBaseConn import SqlServerConn
from decimal import Decimal
import os
import time
###日志开始
from common.setting import ensure_path_sep
from utils.logging_tool.log_control import LogHandler
current_path = os.path.abspath(__file__)
current_dir = os.path.dirname(current_path)
path_list = current_path.split("\\")
dis_path = "\\".join(path_list[-2:-1])


def remove_file(info_path):
    if os.path.exists(info_path):
        os.remove(info_path)
    else:
        print(f"{info_path} 不存在")


info_path = ensure_path_sep(f"\\logs\\info-{dis_path}{time.time()}")
error_path = ensure_path_sep(f"\\logs\\\error-{dis_path}{time.time()}.log")
warning_path = ensure_path_sep(f"\\logs\\warning-{dis_path}{time.time()}.log")
remove_file(info_path)
remove_file(error_path)
remove_file(warning_path)
INFO = LogHandler(info_path, level='info')
ERROR = LogHandler(error_path, level='error')
WARNING = LogHandler(warning_path, level='warning')
###日志结束

class DataComparison:
    def __init__(self,database):
        """
        database为字典类型，支持sqlserver和 mysql库
        key为：库名称
        sqlserver的value值为：sqlserver|ip|端口|用户名|密码|数据库名
        mysql的value值为：mysql|ip|端口|用户名|密码|数据库名
        示列：{'erp库':'sqlserver|ip|端口|用户名|密码|数据库名','金蝶库':'mysql|ip|端口|用户名|密码|数据库名'}
        """
        self.cons={}
        for key,values in database.items():
            conn_data = values.split('|')
            con = SqlServerConn(conn_data[0],conn_data[1], int(conn_data[2]), conn_data[3],
                                                               conn_data[4], conn_data[5])
            self.cons[key]=con


    def data_organization(self,database,sql,keys,values):
        """
        该函数用于将数据处理成字典类型，方便查找
        :param database: 数据库名称
        :param sql: string类型，要执行的sql
        :param keys: 新字典的key，从sql查询字段中取，有多个，传元组
        :param values: 新字典的values，从sql查询字段中取，有多个，传元组
        """
        conn=self.cons.get(database)
        original_data=conn.get_dict(sql)
        if len(original_data) > 0:
            if isinstance(keys,str) and isinstance(values,str):
                original_data_dict = dict(map(lambda x: (x[keys],x[values]),original_data))
            elif isinstance(keys,tuple) and isinstance(values,tuple):
                original_data_dict = dict(map(lambda x: (tuple((x[key] for key in keys)),tuple((x[key] for key in values))), original_data))
            elif isinstance(keys,str) and isinstance(values,tuple):
                original_data_dict = dict(map(lambda x: (x[keys], tuple((x[key] for key in values))), original_data))
            elif isinstance(keys,tuple) and isinstance(values,str):
                original_data_dict = dict(map(lambda x: (tuple((x[key] for key in keys)),x[values]), original_data))
        else:
            return {}
        return original_data_dict

    def data_format(self, num):
        return round(Decimal(num),2)

    def data_compare(self,expect:dict,actual:dict,field):
        loss_actual= set(expect.keys()) - set(actual.keys())
        more_actual = set(actual.keys()) - set(expect.keys())
        #过滤空数据
        if isinstance(field,tuple):
            loss_actual=set(filter(lambda x:sum(expect[x])!=0,loss_actual))
            more_actual=set(filter(lambda x:sum(actual[x])!=0,more_actual))
        else:
            loss_actual = set(filter(lambda x: expect[x] != 0, loss_actual))
            more_actual = set(filter(lambda x: actual[x] != 0, more_actual))
        for i in loss_actual:
            ERROR.logger.error(f"{i}预期有，实际没有 实际少的:{expect[i]} ")
        for i in more_actual:
            ERROR.logger.error(f"{i}预期没有，实际有 实际多的:{actual[i]} ")
        if isinstance(field,str):
            for key, value in expect.items():
                if actual.get(key) and self.data_format(actual.get(key))!=self.data_format(value):
                    ERROR.logger.error(f"{key} {field}不相等：预期：{self.data_format(value)}"
                                       f"实际：{self.data_format(actual.get(key))}"
                                       f"相差：{self.data_format(value)-self.data_format(actual.get(key))}")
        else:
            for key, value in expect.items():
                if actual.get(key) and actual.get(key) != value:
                    for i in range(len(value)):
                        if self.data_format(value[i])!=self.data_format(actual.get(key)[i]):
                            ERROR.logger.error(
                                f"{key} {field[i]}不相等：预期：{self.data_format(value[i])}"
                                f"实际：{self.data_format(actual.get(key)[i])}"
                                f"相差：{self.data_format(value[i])-self.data_format(actual.get(key)[i])}")

